from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity
from app import db
from app.models import Question, QuestionCategory
from app.utils.response import success_response, error_response, paginated_response
from app.utils.decorators import admin_required
from app.models.operation_log import OperationLog
from loguru import logger

questions_bp = Blueprint('questions', __name__)

@questions_bp.route('/categories', methods=['GET'])
def get_categories():
    """获取题目分类列表"""
    try:
        categories = QuestionCategory.query.filter_by(is_active=True).order_by(QuestionCategory.sort_order).all()
        return success_response([category.to_dict() for category in categories])
    except Exception as e:
        logger.error(f"获取题目分类失败: {e}")
        return error_response('获取分类失败', 500)

@questions_bp.route('/', methods=['GET'])
def get_questions():
    """获取题目列表（用户端）"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        category_id = request.args.get('category_id', type=int)
        difficulty = request.args.get('difficulty')
        
        query = Question.query.filter_by(is_active=True)
        
        if category_id:
            query = query.filter_by(category_id=category_id)
        if difficulty:
            query = query.filter_by(difficulty=difficulty)
        
        pagination = query.order_by(Question.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        questions = []
        for question in pagination.items:
            question_dict = question.to_dict_for_exam()  # 不包含正确答案
            question_dict['category'] = question.category.to_dict()
            questions.append(question_dict)
        
        return paginated_response(
            questions,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"获取题目列表失败: {e}")
        return error_response('获取题目列表失败', 500)

# 管理员接口
@questions_bp.route('/admin/categories', methods=['GET'])
@admin_required
def admin_get_categories():
    """管理员获取题目分类列表"""
    try:
        categories = QuestionCategory.query.order_by(QuestionCategory.sort_order).all()
        return success_response([category.to_dict() for category in categories])
    except Exception as e:
        logger.error(f"管理员获取题目分类失败: {e}")
        return error_response('获取分类失败', 500)

@questions_bp.route('/admin/categories', methods=['POST'])
@admin_required
def create_category():
    """创建题目分类"""
    try:
        data = request.get_json()
        name = data.get('name')
        description = data.get('description', '')
        sort_order = data.get('sort_order', 0)
        
        if not name:
            return error_response('分类名称不能为空', 400)
        
        # 检查分类名是否已存在
        existing = QuestionCategory.query.filter_by(name=name).first()
        if existing:
            return error_response('分类名称已存在', 400)
        
        category = QuestionCategory(
            name=name,
            description=description,
            sort_order=sort_order
        )
        
        db.session.add(category)
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = get_jwt_identity().split('_')[1]
        OperationLog.log_operation(
            action='create_question_category',
            description=f'创建题目分类: {name}',
            admin_id=current_admin_id,
            resource_type='question_category',
            resource_id=category.id
        )
        
        return success_response(category.to_dict(), '分类创建成功')
        
    except Exception as e:
        logger.error(f"创建题目分类失败: {e}")
        return error_response('创建分类失败', 500)

@questions_bp.route('/admin/categories/<int:category_id>', methods=['PUT'])
@admin_required
def update_category(category_id):
    """更新题目分类"""
    try:
        category = QuestionCategory.query.get(category_id)
        if not category:
            return error_response('分类不存在', 404)
        
        data = request.get_json()
        name = data.get('name')
        description = data.get('description')
        sort_order = data.get('sort_order')
        is_active = data.get('is_active')
        
        if name is not None:
            # 检查分类名是否已存在（排除自己）
            existing = QuestionCategory.query.filter(
                QuestionCategory.name == name,
                QuestionCategory.id != category_id
            ).first()
            if existing:
                return error_response('分类名称已存在', 400)
            category.name = name
        
        if description is not None:
            category.description = description
        if sort_order is not None:
            category.sort_order = sort_order
        if is_active is not None:
            category.is_active = is_active
        
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = get_jwt_identity().split('_')[1]
        OperationLog.log_operation(
            action='update_question_category',
            description=f'更新题目分类: {category.name}',
            admin_id=current_admin_id,
            resource_type='question_category',
            resource_id=category.id
        )
        
        return success_response(category.to_dict(), '分类更新成功')
        
    except Exception as e:
        logger.error(f"更新题目分类失败: {e}")
        return error_response('更新分类失败', 500)

@questions_bp.route('/admin/', methods=['GET'])
@admin_required
def admin_get_questions():
    """管理员获取题目列表"""
    try:
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        category_id = request.args.get('category_id', type=int)
        difficulty = request.args.get('difficulty')
        question_type = request.args.get('type')
        is_active = request.args.get('is_active', type=lambda v: v.lower() == 'true')
        
        query = Question.query
        
        if category_id:
            query = query.filter_by(category_id=category_id)
        if difficulty:
            query = query.filter_by(difficulty=difficulty)
        if question_type:
            query = query.filter_by(type=question_type)
        if is_active is not None:
            query = query.filter_by(is_active=is_active)
        
        pagination = query.order_by(Question.created_at.desc()).paginate(
            page=page,
            per_page=per_page,
            error_out=False
        )
        
        questions = []
        for question in pagination.items:
            question_dict = question.to_dict()
            question_dict['category'] = question.category.to_dict()
            questions.append(question_dict)
        
        return paginated_response(
            questions,
            page,
            per_page,
            pagination.total
        )
        
    except Exception as e:
        logger.error(f"管理员获取题目列表失败: {e}")
        return error_response('获取题目列表失败', 500)

@questions_bp.route('/admin/', methods=['POST'])
@admin_required
def create_question():
    """创建题目"""
    try:
        data = request.get_json()
        category_id = data.get('category_id')
        question_type = data.get('type')
        difficulty = data.get('difficulty', 'medium')
        title = data.get('title')
        content = data.get('content', '')
        options = data.get('options')
        correct_answer = data.get('correct_answer')
        explanation = data.get('explanation', '')
        score = data.get('score', 10)
        
        if not all([category_id, question_type, title, correct_answer]):
            return error_response('分类ID、题目类型、标题和正确答案不能为空', 400)
        
        # 检查分类是否存在
        category = QuestionCategory.query.get(category_id)
        if not category:
            return error_response('分类不存在', 400)
        
        # 验证题目类型
        valid_types = ['single_choice', 'multiple_choice', 'true_false', 'fill_blank']
        if question_type not in valid_types:
            return error_response('无效的题目类型', 400)
        
        # 验证难度等级
        valid_difficulties = ['easy', 'medium', 'hard']
        if difficulty not in valid_difficulties:
            return error_response('无效的难度等级', 400)
        
        current_admin_id = int(get_jwt_identity().split('_')[1])
        
        question = Question(
            category_id=category_id,
            type=question_type,
            difficulty=difficulty,
            title=title,
            content=content,
            options=options,
            correct_answer=correct_answer,
            explanation=explanation,
            score=score,
            created_by=current_admin_id
        )
        
        db.session.add(question)
        db.session.commit()
        
        # 记录操作日志
        OperationLog.log_operation(
            action='create_question',
            description=f'创建题目: {title[:50]}...',
            admin_id=current_admin_id,
            resource_type='question',
            resource_id=question.id
        )
        
        return success_response(question.to_dict(), '题目创建成功')
        
    except Exception as e:
        logger.error(f"创建题目失败: {e}")
        return error_response('创建题目失败', 500)

@questions_bp.route('/admin/<int:question_id>', methods=['PUT'])
@admin_required
def update_question(question_id):
    """更新题目"""
    try:
        question = Question.query.get(question_id)
        if not question:
            return error_response('题目不存在', 404)
        
        data = request.get_json()
        category_id = data.get('category_id')
        question_type = data.get('type')
        difficulty = data.get('difficulty')
        title = data.get('title')
        content = data.get('content')
        options = data.get('options')
        correct_answer = data.get('correct_answer')
        explanation = data.get('explanation')
        score = data.get('score')
        is_active = data.get('is_active')
        
        if category_id is not None:
            # 检查分类是否存在
            category = QuestionCategory.query.get(category_id)
            if not category:
                return error_response('分类不存在', 400)
            question.category_id = category_id
        
        if question_type is not None:
            valid_types = ['single_choice', 'multiple_choice', 'true_false', 'fill_blank']
            if question_type not in valid_types:
                return error_response('无效的题目类型', 400)
            question.type = question_type
        
        if difficulty is not None:
            valid_difficulties = ['easy', 'medium', 'hard']
            if difficulty not in valid_difficulties:
                return error_response('无效的难度等级', 400)
            question.difficulty = difficulty
        
        if title is not None:
            question.title = title
        if content is not None:
            question.content = content
        if options is not None:
            question.options = options
        if correct_answer is not None:
            question.correct_answer = correct_answer
        if explanation is not None:
            question.explanation = explanation
        if score is not None:
            question.score = score
        if is_active is not None:
            question.is_active = is_active
        
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = int(get_jwt_identity().split('_')[1])
        OperationLog.log_operation(
            action='update_question',
            description=f'更新题目: {question.title[:50]}...',
            admin_id=current_admin_id,
            resource_type='question',
            resource_id=question.id
        )
        
        return success_response(question.to_dict(), '题目更新成功')
        
    except Exception as e:
        logger.error(f"更新题目失败: {e}")
        return error_response('更新题目失败', 500)

@questions_bp.route('/admin/<int:question_id>', methods=['DELETE'])
@admin_required
def delete_question(question_id):
    """删除题目"""
    try:
        question = Question.query.get(question_id)
        if not question:
            return error_response('题目不存在', 404)
        
        title = question.title
        db.session.delete(question)
        db.session.commit()
        
        # 记录操作日志
        current_admin_id = int(get_jwt_identity().split('_')[1])
        OperationLog.log_operation(
            action='delete_question',
            description=f'删除题目: {title[:50]}...',
            admin_id=current_admin_id,
            resource_type='question',
            resource_id=question_id
        )
        
        return success_response(None, '题目删除成功')
        
    except Exception as e:
        logger.error(f"删除题目失败: {e}")
        return error_response('删除题目失败', 500)

@questions_bp.route('/admin/batch-import', methods=['POST'])
@admin_required
def batch_import_questions():
    """批量导入题目"""
    try:
        data = request.get_json()
        questions_data = data.get('questions', [])
        category_id = data.get('category_id')
        
        if not questions_data:
            return error_response('题目数据不能为空', 400)
        
        if not category_id:
            return error_response('分类ID不能为空', 400)
        
        # 检查分类是否存在
        category = QuestionCategory.query.get(category_id)
        if not category:
            return error_response('分类不存在', 400)
        
        current_admin_id = int(get_jwt_identity().split('_')[1])
        success_count = 0
        error_count = 0
        
        for question_data in questions_data:
            try:
                question = Question(
                    category_id=category_id,
                    type=question_data.get('type', 'single_choice'),
                    difficulty=question_data.get('difficulty', 'medium'),
                    title=question_data.get('title'),
                    content=question_data.get('content', ''),
                    options=question_data.get('options'),
                    correct_answer=question_data.get('correct_answer'),
                    explanation=question_data.get('explanation', ''),
                    score=question_data.get('score', 10),
                    created_by=current_admin_id
                )
                
                db.session.add(question)
                success_count += 1
                
            except Exception as e:
                logger.error(f"导入题目失败: {e}")
                error_count += 1
                continue
        
        db.session.commit()
        
        # 记录操作日志
        OperationLog.log_operation(
            action='batch_import_questions',
            description=f'批量导入题目: 成功{success_count}个，失败{error_count}个',
            admin_id=current_admin_id,
            resource_type='question'
        )
        
        return success_response({
            'success_count': success_count,
            'error_count': error_count
        }, f'批量导入完成，成功{success_count}个，失败{error_count}个')
        
    except Exception as e:
        logger.error(f"批量导入题目失败: {e}")
        return error_response('批量导入失败', 500) 